home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / parser / tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-18  |  16.4 KB  |  925 lines

  1. # include    <stdio.h>
  2. # include    <ingres.h>
  3. # include    <aux.h>
  4. # include    <tree.h>
  5. # include    <pv.h>
  6. # include    "parser.h"
  7. # include    <symbol.h>
  8. # include    <malloc.h>
  9. # include    <errors.h>
  10.  
  11. /*
  12. ** TREE
  13. **      FUNCTION TO ADD NODE TO QUERY TREE
  14. **    RETURN VALUE IS POINTER TO NODE JUST CREATED        
  15. */
  16. QTREE *
  17. tree(lptr, rptr, typ, len, valu, attnum)
  18. QTREE            *lptr;
  19. QTREE            *rptr;
  20. char            typ;
  21. int            len;
  22. register int        valu;
  23. register struct atstash    *attnum;
  24. {
  25.     register QTREE    *tptr;
  26.     extern char    Trfrmt;
  27.     extern char    Trfrml;
  28.     extern char    *need();
  29.     extern QTREE    *norm();
  30.     extern int    Err_current;
  31.  
  32. # ifdef    xPTR3
  33.     tTfp(55, 0, "tree type(%d), len(%d), value(%d).\n", typ, len, valu);
  34. # endif
  35.  
  36.     if (Err_current)
  37.         return (NULL);
  38.  
  39.     /* Following is a hack.  Sorry about that John.  */
  40.     if (typ == AND)
  41.         len = sizeof (struct rootnode) - sizeof (short);
  42.     
  43.     tptr = (QTREE *) need(Qbuf, QT_HDR_SIZ + len);
  44.     tptr->left = lptr;
  45.     tptr->right = rptr;
  46.     tptr->sym.type = typ;
  47.     tptr->sym.len = len;
  48.  
  49.     switch (typ)
  50.     {
  51.       case VAR:
  52.         tptr->sym.value.sym_var.varno = valu & I1MASK;
  53.         tptr->sym.value.sym_var.attno = attnum->atbid;
  54.         tptr->sym.value.sym_var.varfrmt = attnum->atbfrmt;
  55.         tptr->sym.value.sym_var.varfrml = attnum->atbfrml;
  56.         tptr->sym.value.sym_var.valptr = NULL;
  57.         tptr->sym.value.sym_var.varstr = NULL;
  58.         break;
  59.  
  60.       case ROOT:
  61.       case AGHEAD:
  62.         tptr->sym.value.sym_root.rootuser = valu;
  63.         break;
  64.  
  65.       case TREE:
  66.       case BYHEAD:
  67.       case AND:
  68.       case OR:
  69.       case QLEND:
  70.         break;
  71.  
  72.       case UOP:
  73.       case BOP:
  74.         tptr->sym.value.sym_op.opno = valu;
  75.         format(tptr);
  76.         break;
  77.  
  78.       case COP:
  79.         if ((tptr->sym.value.sym_op.opno = getcop(valu)) == BADCOP)
  80.         {
  81.             /* bad const operator */
  82.             par_error(BADCONSTOP, WARN, valu, 0);
  83.             return(NULL);
  84.         }
  85.         break;
  86.  
  87.       case AOP:
  88.         format(tptr->right);
  89.         tptr->sym.value.sym_op.agfrmt = Trfrmt;
  90.         tptr->sym.value.sym_op.agfrml = Trfrml;
  91.  
  92.       case RESDOM:
  93.         tptr->sym.value.sym_resdom.resno = valu;
  94.         format(tptr);
  95.         tptr->sym.value.sym_resdom.resfrmt = Trfrmt;
  96.         tptr->sym.value.sym_resdom.resfrml = Trfrml;
  97.         break;
  98.  
  99.       default:
  100.         /* INT, FLOAT, CHAR */
  101.         bmove(valu, &tptr->sym.value, len & I1MASK);
  102.         break;
  103.     }
  104.     return (tptr);
  105. }
  106.  
  107. /*
  108. ** WINDUP
  109. **    assign resno's to resdoms of an agg fcn
  110. */
  111. windup(ptr)
  112. QTREE    *ptr;
  113. {
  114.     register int            tot;
  115.     register int            kk;
  116.     register QTREE            *t;
  117.  
  118.     /* COUNT THE RESDOM'S OF THIS TARGET LIST */
  119.     kk = 1;
  120.     for (t = ptr; t; t = t->left)
  121.         kk++;
  122.     tot = 1;
  123.     for (t=ptr; t;t = t->left)
  124.         t->sym.value.sym_resdom.resno = kk - tot++;
  125. }
  126.  
  127. /*
  128. ** ADDRESDOM - makes a new entry for the target list
  129. **
  130. **    Trname must contain the name of the resdom to
  131. **    use for the header, create and Rsdmno for append, replace
  132. **
  133. **    the parameters are pointers to the subtrees to be
  134. **    suspended from the node
  135. */
  136. QTREE *
  137. addresdom(lptr, rptr)
  138. QTREE    *lptr, *rptr;
  139. {
  140.     register QTREE    *rtval;
  141.     register struct atstash        *aptr;
  142.     char                buf[10];    /* buffer type and length in ascii for dbu */
  143.  
  144.     extern int            Opflag;
  145.     extern int            Rsdmno;
  146.     extern int            Equel;
  147.     extern int            Resrng;
  148.     extern char            Trfrmt;
  149.     extern char            Trfrml;
  150.     extern char            *Trname;
  151.     extern PARRNG            Parrng[];
  152.  
  153.     extern QTREE            *tree();
  154.     extern struct atstash        *attlookup();
  155.  
  156.     int                temp;
  157.  
  158.     switch (Opflag)
  159.     {
  160.       case mdSTOP:
  161.         rtval = NULL;
  162.         break;
  163.       case mdRETR:
  164.       case mdRET_UNI:
  165.       case mdVIEW:
  166.         Rsdmno++;
  167.         if (Rsdmno >= MAXDOM)
  168.             /* too many resdoms */
  169.             par_error(RESXTRA, FATAL, 0);
  170.         rtval = tree(lptr, rptr, RESDOM, sizeof (struct resdomnode), Rsdmno);
  171.         if (!Equel || Resrng)
  172.         {
  173.             /* buffer info for header or CREATE */
  174.             setp(PV_STR, Trname);
  175.  
  176.             buf[0] = Trfrmt & I1MASK;
  177.             smove(iocv(Trfrml & I1MASK), &buf[1]);
  178.  
  179.             setp(PV_STR, buf);
  180.         }
  181.         break;
  182.  
  183.       default:
  184.         /*
  185.         ** for append and replace, the result domain
  186.         ** number is determined by the location of
  187.         ** the attribute in the result relation
  188.         */
  189.         if (sequal(Trname, "tid"))
  190.             /* attrib not found */
  191.             par_error(NOATTRIN, WARN, Trname,
  192.                 trim_relname(Parrng[Resrng].vardesc.reldum.relid), 0);
  193. #        ifdef    DISTRIB
  194.         if (sequal(Trname, "sid"))
  195.             /* attrib not found */
  196.             par_error(NOATTRIN, WARN, Trname,
  197.                 trim_relname(Parrng[Resrng].vardesc.reldum.relid), 0);
  198. #        endif
  199.         aptr = attlookup(Resrng, Trname);
  200.         Rsdmno = aptr->atbid;
  201.         rtval = tree(lptr, rptr, RESDOM, sizeof (struct resdomnode), Rsdmno);
  202.         if (Opflag != mdPROT)    /* INTEGRITY not possible here */
  203.             attcheck(aptr);
  204.         break;
  205.     }
  206.     return (rtval);
  207. }
  208. /*
  209. ** GETCOP
  210. **    routine to lookup 'string' in constant operators table
  211. **    constant table is declared in tables.y
  212. **    structure is defined in ../parser.h
  213. */
  214. getcop(string)
  215. char    *string;
  216. {
  217.     register struct constop    *cpt;
  218.     register char        *sptr;
  219.     extern struct constop    Coptab[];
  220.  
  221.     sptr = string;
  222.     for (cpt = Coptab; cpt->copname; cpt++)
  223.         if (sequal(sptr, cpt->copname))
  224.             return (cpt->copnum);
  225.     return (BADCOP);
  226. }
  227.  
  228. /*
  229. ** SUBSTRING
  230. **    creates structure to save delimiters of a substring
  231. **    structure is defined in ../h/tree.h
  232. */
  233. STRKEEPER
  234. *substring(str,isname)
  235. char    *str;
  236. int     isname;
  237. {
  238.     extern char    *need();
  239.     STRKEEPER    *s;
  240.  
  241.     s = (STRKEEPER *) need(Qbuf,sizeof(STRKEEPER));
  242.     s->number[1] = s->number[0] = 1;
  243.     s->string[1] = NULL;
  244.     s->flag[0] = s->flag[1] = 0;
  245.     s->string[0] = str;
  246.     if (isname)
  247.         s->flag[0] = 1;
  248.     if (str == NULL)
  249.         s->flag[0] |= 2;
  250.     return(s);
  251. }
  252.  
  253. STRKEEPER
  254. *endvals(interval,left,right)
  255. STRKEEPER *interval;
  256. int      left,right;
  257. {
  258.     if (left == '(')
  259.         interval->type[0] = OPEN;
  260.     else
  261.         interval->type[0] = CLOSED;
  262.     if (right == ')')
  263.         interval->type[1] = OPEN;
  264.     else
  265.         interval->type[1] = CLOSED;
  266.     return(interval);
  267. }
  268.  
  269. setnumber(interval,num)
  270. STRKEEPER *interval;
  271. short      *num;
  272. {
  273.     interval->number[0] = *num;
  274. }
  275.  
  276.  
  277. groupstrings(left,right)
  278. STRKEEPER *left,*right;
  279. {
  280.     left->string[1] = right->string[0];
  281.     left->flag[1] = right->flag[0];
  282.     left->number[1] = right->number[0];
  283. }
  284.  
  285.  
  286. /*
  287. **    CHECK_BNF -- check the legality of a simplified BNF defnition
  288. **
  289. **        Parameters: 
  290. **            str-- the string to be checked
  291. **    
  292. **        Returns:
  293. **            0 - the string is legal
  294. **            <0 - the string is not legal
  295. **                -1 : bracket,brace not matched
  296. **                -2 : hyphen misused
  297. **
  298. **        Called by:
  299. **            make_tuples
  300. **
  301. **        Comments: 
  302. **            the string may not contain nested braces or brackets
  303. **            these chars have special meaning and must be 
  304. **            backslashed: { } [ ] - \
  305. **
  306. */
  307.  
  308. check_bnf(str)
  309. char    *str;
  310. {
  311.     char    *temp;        /* temp ptr to string */
  312.     int    len;        /* length of string */
  313.     char    ch;        /* ptr to one char of string */
  314.     char     nextch;
  315.     int    inbrace=0;    /* keeps track of braces */
  316.     int     inbrak=0;    /* keeps track of brackets */
  317.  
  318.  
  319.     len = strlen(str);
  320.     temp = str;
  321.  
  322.     while (len > 0)
  323.     {
  324.         len--;
  325.         ch = *temp++;
  326.  
  327.         switch (ch)
  328.         {
  329.             case LBRACKET:
  330.             if (!inbrace)
  331.                 inbrak++;
  332.             else
  333.                 return(-1);
  334.             break;
  335.             case RBRACKET:
  336.             inbrak--;
  337.             if (inbrak != 0)
  338.                 return(-1);
  339.             break;
  340.             case LBRACE:
  341.             if (!inbrak)
  342.                 inbrace++;
  343.             else
  344.                 return(-1);
  345.             break;
  346.             case RBRACE:
  347.             inbrace--;
  348.             if (inbrace != 0)
  349.                 return(-1);
  350.             break;
  351.             case '-':
  352.             return(-2);
  353.             break;
  354.             case '\\':
  355.             *temp++;
  356.             break;
  357.             default:
  358.             nextch = *temp;
  359.             if (nextch == '-')
  360.             {
  361.                 *temp++;
  362.                 len--;
  363.                 if (!len)
  364.                     return(-2);
  365.                 ch = *temp;
  366.                 switch(ch)
  367.                 {
  368.                     case LBRACKET:
  369.                     case RBRACKET:
  370.                     case LBRACE:
  371.                     case RBRACE:
  372.                     case '-':
  373.                     return(-2);
  374.                     break;
  375.                     case '\\':
  376.                     *temp++;
  377.                     break;
  378.                     default:
  379.                     break;
  380.                 }
  381.             }
  382.         }
  383.     }
  384.     if ((inbrace) || (inbrak))
  385.         return(-1);
  386.     return(0);
  387. }
  388.  
  389.  
  390. /*
  391. **    MAKE_TUPLES -- create the tuples for the 'rdelim' relation
  392. **            as specified by a user-defined delimitor
  393. **
  394. **        Paramaters:
  395. **            desc--descriptor for the relation
  396. **            group--group name for the delimitor
  397. **            delim--name of the delimitor
  398. **            str-bnf string specifying the delimitor
  399. **
  400. **        Returns:
  401. **            0 if successful
  402. **            <0 if not successful
  403. **            -1,-2: BNF expression not legal
  404. **
  405. */
  406. make_tuples(desc,group,delim,str)
  407. DESC     *desc;
  408. char    *group;
  409. char    *delim;
  410. char    *str;
  411. {
  412.     int    err;        /* error status of bnf string */
  413.     char    *map;        /* pointer to next string to make into bitmap */
  414.     int    len;        /* len of str */
  415.     int     mlen;        /* len of substring to make into bitmap */
  416.     int     order;        /* order of bitmap */
  417.     int     type;        /* type of interval ONE or ZEROMORE */
  418.     char    ch;        /* pointer to current char */
  419.  
  420.     err = check_bnf(str);
  421.     if (err < 0)
  422.         return(err);
  423.  
  424.     len = strlen(str);
  425.     order = 0;
  426.  
  427.     while (len > 0)
  428.     {
  429.         order++;
  430.         map = str;
  431.         mlen = 0;
  432.  
  433.         ch = *str++;
  434.         len--;
  435.  
  436.         switch (ch)
  437.         {
  438.             case LBRACKET:
  439.                 type = ONE;
  440.                 map = str;
  441.                 while ((ch = *str++) != RBRACKET)
  442.                 {
  443.                 mlen++;
  444.                 len--;
  445.                 if (ch == '\\')
  446.                 {
  447.                     ch = *str++;
  448.                     mlen++;
  449.                     len--;
  450.                 }
  451.                 }
  452.                 len--;
  453.                 break;
  454.             
  455.             case LBRACE:
  456.                 type = ZEROMORE;
  457.                 map = str;
  458.                 while ((ch = *str++) != RBRACE)
  459.                 {
  460.                 mlen++;
  461.                 len--;
  462.                 if (ch == '\\')
  463.                 {
  464.                     ch = *str++;
  465.                     mlen++;
  466.                     len--;
  467.                 }
  468.                 }
  469.                 len--;
  470.                 break;
  471.  
  472.             default:
  473.                 type = ONE;
  474.                 if (ch == '\\')
  475.                 {
  476.                 map = str;
  477.                 ch = *str++;
  478.                 len--;
  479.                 mlen = 1;
  480.                 }
  481.                 if (*str == '-')
  482.                 {
  483.                 *str++;
  484.                 len--;
  485.                 mlen++;
  486.                 *str++;
  487.                 len--;
  488.                 mlen++;
  489.                 }
  490.                 else
  491.                 mlen = 1;
  492.                 break;
  493.         }
  494.  
  495.         create_tup(desc,order,group,delim,type,map,mlen);
  496.     }
  497.     return(0);
  498. }
  499.  
  500.  
  501.  
  502. /*
  503. **    CREATE_TUP-- create a tuple in the 'rdelim' relation
  504. **
  505. **        Parameters:
  506. **            desc - descriptor for the relation
  507. **            order - order field for tuple
  508. **            group - group field for tuple
  509. **            delim - delim field for tuple
  510. **            type - type field for tuple
  511. **            str - string to be converted into bitmap
  512. **            strlen - length of str
  513. **
  514. **        Called by:
  515. **            make_tuples
  516. */
  517. create_tup(desc,order,group,delim,type,str,strlen)
  518. DESC    *desc;
  519. int    order;
  520. char    *group;
  521. char    *delim;
  522. int    type;
  523. char    *str;
  524. int    strlen;
  525. {
  526.     DELIM_TUP    *tuple;
  527.     char        bitmap[BITMAPLEN];
  528.     TID        *tid;
  529.     char        *make_dmap();
  530.     char        b[BITMAPLEN];
  531.     int        i;
  532.  
  533.  
  534.     tuple = (DELIM_TUP *) malloc (sizeof(DELIM_TUP));
  535.     tuple->order = order;
  536.     strcpy(tuple->group,group);
  537.     strcpy(tuple->delim,delim);
  538.     tuple->type = type;
  539.  
  540.     make_dmap(str,strlen,b);
  541.     for ( i= 0; i< BITMAPLEN; i++)
  542.         tuple->bitmap[i] = b[i];
  543.  
  544.     insert(desc,&tid,tuple,1);
  545. }
  546.  
  547.  
  548. /*
  549. **    MAKE_DMAP -- given a BNF string, make the corresponding bitmap
  550. **
  551. **        Parameters:
  552. **            str - BNF string
  553. **             len - length of string
  554. **        
  555. **        Called by:
  556. **            create_tup
  557. **
  558. **        Returns:
  559. **            pointer to the bitmap of 16 chars
  560. **
  561. **        Comments:
  562. **            The bitmap is formed of 16 chars. The total bits
  563. **        (128) represents the characters of the ASCII set.
  564. **        If the BNF string indicates a character, the bit
  565. **        corresponding to that char is set in the bitmap.
  566. **        All other bits are reset.
  567. */
  568. char *
  569. make_dmap(str,len,b)
  570. char    *str;
  571. int    len;
  572. char    *b;
  573. {
  574.     char    ch;
  575.     char    nextch;
  576.     int    i;
  577.  
  578. # ifdef xPTR3
  579.     tTfp(42,0,"DMAP: str = %s, len = %d\n",str,len);
  580. # endif
  581.     for (i = 0; i < ACHARS; i++)
  582.         reset(b,i);
  583.  
  584.     while (len > 0)
  585.     {
  586.         ch = *str++;
  587.         len--;
  588.         if (ch == '\\')
  589.         {
  590.             ch = *str++;
  591.             len--;
  592.         }
  593.         if ( (len > 0) && (*str == '-'))
  594.         {
  595.             *str++;
  596.             len--;
  597.             nextch = *str++;
  598.             len--;
  599.             for (i = ch; i <= nextch; i++)
  600.             {
  601.                 set(b,i);
  602.             }
  603.         }
  604.         else
  605.         {    
  606.             set(b,ch);
  607.         }
  608.     }
  609.     return(b);
  610. }
  611.  
  612. /*
  613. **    SET,RESET -- bitmap setting routines
  614. **
  615. **        Parameters:
  616. **            map: the array of chars which forms the bitmap
  617. **            n: the bit to set or reset
  618. **    
  619. **        Called by:
  620. **            make_bitmap
  621. **
  622. */
  623. set(map,n)
  624. char     *map;
  625. int    n;
  626. {
  627.     map[n/BITS] |= (1<<(n%BITS));
  628. }
  629.  
  630. reset(map,n)
  631. char    *map;
  632. int    n;
  633. {
  634.     map[n/BITS] &= ((1<<(n%BITS)) ^ MAXFIELD); 
  635. }
  636.  
  637. test(map,n)
  638. char    *map;
  639. int    n;
  640. {
  641.     return ((map[n/BITS] & (1<<(n%BITS))) != 0);
  642. }
  643.  
  644. /*
  645. **    MAKE_LIST -- puts the delimitors to be used in the delim queue
  646. **
  647. **        Parameters:
  648. **            desc - descriptor for the relation
  649. **            group - group of delims to use
  650. **
  651. **        Returns:
  652. **            0 if ok
  653. **            -1 if no delims could be found in the specified group
  654. **
  655. **        Comments:
  656. **            given a group name, adds all delimitors in that
  657. **            group to the head of the delim queue, which is
  658. **            pointed to by Delimhead.
  659. **            if the queue is empty, the predefined delimitors
  660. **            'w' and 'c' will be added to the list
  661. */
  662.  
  663. extern DELIMLIST *Delimhead;
  664.  
  665. make_list(desc,group)
  666. DESC     *desc;
  667. char    *group;
  668. {
  669.     DELIM_TUP        tuple;
  670.     TID            lotid, hitid;
  671.     DELIMLIST        *d;
  672.     DMAP            *map, *m;
  673.     char            delim[12];
  674.     int            start = 1;
  675.     int            i;
  676.     int            notfound = 1;
  677.  
  678. # ifdef xPTR3
  679.     tTfp(42,0,"Make_list: group = %s\n", group);
  680. # endif
  681.     if (!strcmp (group,"system"))
  682.     {
  683.         predef_delims();
  684.         return(0);
  685.     }
  686.     if (find(desc,LRANGEKEY, &lotid, &hitid, group) < 0)
  687.         return(-1);
  688.     find(desc,HRANGEKEY, &lotid, &hitid, group);
  689.     while (!get(desc, &lotid, &hitid, &tuple, 1))
  690.     {
  691.         if (strcmp(tuple.group, group))
  692.         {
  693.             continue;
  694.         }
  695.         notfound = FALSE;
  696.         /* check if it is a new delimitor */
  697.         if (strcmp(tuple.delim, delim))
  698.             start = 1;
  699.  
  700.         /* start a new delimitor node */
  701.         if (start)
  702.         {
  703.             d = (DELIMLIST *) malloc( sizeof(DELIMLIST)); 
  704.             strcpy(delim, tuple.delim);
  705.             strcpy(d->group,tuple.group);
  706.             strcpy(d->delim,delim);
  707.             d->back = Delimhead;
  708.             Delimhead = d;
  709.  
  710.             map = (DMAP *) malloc(sizeof(DMAP));
  711.             map->order = tuple.order;
  712.             map->type = tuple.type;
  713.             for ( i = 0; i < BITMAPLEN; i++)
  714.                 map->bits[i] = tuple.bitmap[i];
  715.             map->next = NULL;
  716.             d->maptr = map;
  717.             m = map;
  718.             start = 0;
  719.  
  720.         }
  721.         else     /* add another bitmap to the delimitor node */
  722.         {
  723.             map = (DMAP *) malloc(sizeof(DMAP));
  724.             map->order = tuple.order;
  725.             map->type = tuple.type;
  726.             for ( i = 0; i < BITMAPLEN; i++)
  727.                 map->bits[i] = tuple.bitmap[i];
  728.             map->next = NULL;
  729.             m->next = map;
  730.             m = m->next;
  731.  
  732.         }
  733.  
  734.     }
  735.     /*prlist(Delimhead); */
  736.     if (notfound)
  737.         return(-1);
  738.     return(0);
  739. }
  740.  
  741. /*
  742. **    PREDEF_DELIMS - add the predefined delims to the queue
  743. **
  744. **        Called by:
  745. **            make_list
  746. **
  747. **        Side Effects:
  748. **            the delim queue pointed to by Delimhead
  749. **            is initialized with the delims 'w' and 'c'.
  750. **
  751. */
  752. predef_delims()
  753. {
  754.     DELIMLIST    *d;
  755.     DMAP        *m, *m2;
  756.     int        i;
  757.  
  758.     d = (DELIMLIST * ) malloc(sizeof(DELIMLIST));
  759.     strcpy(d->group, "system");
  760.     strcpy(d->delim, "c");
  761.     d->back = NULL;
  762.  
  763.     m = (DMAP *) malloc(sizeof (DMAP));
  764.     m->order = 1;
  765.     m->type = ONE;
  766.     bzero(m->bits, sizeof(m->bits));
  767.     for (i = ' '; i <= '~'; i++)
  768.         set(m->bits, i);
  769.     m->next = NULL;
  770.     d->maptr = m;
  771.     Delimhead = d;
  772.  
  773.  
  774.     d = (DELIMLIST * ) malloc(sizeof(DELIMLIST));
  775.     strcpy(d->group, "system");
  776.     strcpy(d->delim, "w");
  777.     d->back = NULL;
  778.     m = (DMAP *) malloc(sizeof (DMAP));
  779.     m->order = 1;
  780.     m->type = ONE;
  781.     bzero(m->bits, sizeof(m->bits));
  782.     for (i = 'A'; i <= 'Z'; i++)
  783.         set(m->bits, i);
  784.     for (i = 'a'; i <= 'z'; i++)
  785.         set(m->bits, i);
  786.     d->maptr = m;
  787.  
  788.     m2 = (DMAP *) malloc(sizeof(DMAP));
  789.     m2->order = 2;
  790.     m2->type = ZEROMORE;
  791.     bzero(m2->bits, sizeof(m->bits));
  792.     for (i = 'A'; i <= 'Z'; i++)
  793.         set(m2->bits, i);
  794.     for (i = 'a'; i <= 'z'; i++)
  795.         set(m2->bits, i);
  796.     m->next = m2;
  797.     m2->next = NULL;
  798.  
  799.     d->back = Delimhead;
  800.     Delimhead = d;
  801. }
  802.  
  803.  
  804.  
  805.  
  806.  
  807. /*
  808. **    PRLIST -- print contents of delimiter queue
  809. */
  810. prlist(d)
  811. struct delimlist    *d;
  812. {
  813.     struct delimlist    *q;
  814.     DMAP            *m;
  815.     int            i;
  816.  
  817.     printf("DELIM QUEUE:\n");
  818.     q = d;
  819.     while (q != NULL)
  820.     {
  821.         printf("-------------------------------------------------------\n");
  822.         printf("NODE:   group= %s,  delim = %s \n", q->group, q->delim);
  823.         m = q->maptr;
  824.         while (m != NULL)
  825.         {
  826.             printf("maps:\n");
  827.             printf("order = %d, type = %d \n", m->order, m->type);
  828.             for (i = 0; i < ACHARS; i++)
  829.                 printf("%d ", test(m->bits,i));
  830.             printf("\n");
  831.             m = m->next;
  832.         }
  833.         q = q->back;
  834.         printf("-------------------------------------------------------\n");
  835.     }
  836.  
  837.         return(0);
  838.  
  839. }
  840.  
  841. /*
  842. **    SHRINK_LIST -- remove the delims in specified group from list
  843. **
  844. **        Parameters:
  845. **            group - name of the group to remove
  846. **
  847. */
  848. shrink_list(group)
  849. char    *group;
  850. {
  851.     struct delimlist        *p, *q;
  852.  
  853.     /* may not delete sytem delims */
  854.     if (!strcmp(group, "system"))
  855.         return(-1);
  856.  
  857.     p = Delimhead;
  858.  
  859.     while ((p != NULL) && (strcmp(p->group, group)))
  860.     {
  861.         q = p;
  862.         p = p->back;
  863.     }
  864.     if (p == NULL)
  865.     {
  866.         return(-1);    /* error group not found */
  867.     }
  868.  
  869.     while(!strcmp(p->group, group))
  870.     {
  871.         if (p == Delimhead)
  872.             Delimhead = p->back;
  873.         else
  874.             q->back = p->back;
  875.         
  876.         if (p->back ==  NULL)
  877.         {
  878.             return(0);
  879.         }
  880.  
  881.         p = p-> back;
  882.     }
  883.  
  884.     /* prlist(Delimhead); */
  885.     return(0);
  886. }
  887.  
  888. /*
  889. **    DESTROY_DELIM -- remove the group of delims from the relation 'rdelim'
  890. **
  891. **        Parameters:
  892. **            group - the group of delims to remove
  893. **
  894. **        Called By:
  895. **            grammar.y
  896. **    
  897. **        Returns:
  898. **            0 if delims were successfully removed
  899. **            -1 if delims were not found in relation
  900. */
  901. destroy_delim(desc, group)
  902. DESC    *desc;
  903. char    *group;
  904. {
  905.     DELIM_TUP    tuple;
  906.     TID        lotid,hitid;
  907.     int        notfound = 1;
  908.  
  909.     if (find(desc,LRANGEKEY, &lotid, &hitid, group) < 0)
  910.         return(-1);
  911.     find(desc,HRANGEKEY, &lotid, &hitid, group);
  912.  
  913.     while (!get(desc, &lotid, &hitid, &tuple, 1))
  914.     {
  915.         if (!strcmp(tuple.group, group))
  916.         {
  917.             notfound = 0;
  918.             delete(desc,&lotid);
  919.         }
  920.     }
  921.     if (notfound) 
  922.         return(-1);
  923.     return(0);
  924. }
  925.